home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / include / glibmm-2.4 / glibmm / containers.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-04-20  |  9.1 KB  |  373 lines

  1. // -*- c++ -*-
  2. #ifndef _GLIBMM_CONTAINERS_H
  3. #define _GLIBMM_CONTAINERS_H
  4.  
  5. /* $Id: containers.h,v 1.6 2005/01/21 19:26:04 murrayc Exp $ */
  6.  
  7. /* containers.h
  8.  *
  9.  * Copyright (C) 1998-2002 The gtkmm Development Team
  10.  *
  11.  * This library is free software; you can redistribute it and/or
  12.  * modify it under the terms of the GNU Library General Public
  13.  * License as published by the Free Software Foundation; either
  14.  * version 2 of the License, or (at your option) any later version.
  15.  *
  16.  * This library is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  19.  * Library General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU Library General Public
  22.  * License along with this library; if not, write to the Free
  23.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25.  
  26. #include <glib/glist.h>
  27. #include <glib/gslist.h>
  28. #include <glibmm/sarray.h> /* for backward compatibility */
  29.  
  30. #include <iterator>
  31. #include <glibmmconfig.h>
  32.  
  33. GLIBMM_USING_STD(bidirectional_iterator_tag)
  34. GLIBMM_USING_STD(forward_iterator_tag)
  35.  
  36.  
  37. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  38.  
  39. namespace Glib
  40. {
  41.  
  42. template <class T> class List_Iterator;
  43. template <class T> class List_ConstIterator;
  44. template <class T> class List_ReverseIterator;
  45.  
  46. // Most of these methods in the non-template classes needs to be moved
  47. // to implementation.
  48.  
  49. //Daniel Elstner has ideas about generating these per-widget with m4. murrayc.
  50.  
  51.  
  52. extern GLIBMM_API gpointer glibmm_null_pointer;
  53.  
  54. template <class T>
  55. class List_Iterator_Base
  56. {
  57. public:
  58.   typedef T  value_type;
  59.   typedef T* pointer;
  60.   typedef T& reference;
  61. } ;
  62.  
  63. ///For instance, List_Iterator< Gtk::Widget >
  64. template <class T>
  65. class List_Iterator : public List_Iterator_Base<T>
  66. {
  67. public:
  68.   typedef std::bidirectional_iterator_tag iterator_category;
  69.   typedef size_t size_type;
  70.   typedef ptrdiff_t difference_type;
  71.   
  72.   typedef typename List_Iterator_Base<T>::pointer pointer;
  73.   typedef typename List_Iterator_Base<T>::reference reference;
  74.  
  75.   GList* const* head_;
  76.   GList* node_;
  77.  
  78.   typedef List_Iterator<T> Self;
  79.  
  80.   List_Iterator(GList* const& head, GList* node)
  81.   : head_(&head), node_(node)
  82.   {}
  83.  
  84.   List_Iterator()
  85.    : head_(0), node_(0)
  86.   {}
  87.  
  88.   List_Iterator(const Self& src)
  89.   : head_(src.head_), node_(src.node_)
  90.   {}
  91.  
  92.   bool operator==(const Self& src) const { return node_ == src.node_; }
  93.   bool operator!=(const Self& src) const { return node_ != src.node_; }
  94.  
  95.   Self&  operator++()
  96.   {
  97.     if (!node_)
  98.       node_ = g_list_first(*head_);
  99.     else
  100.       node_ = (GList*)g_list_next(node_);
  101.     return *this;
  102.   }
  103.  
  104.   Self operator++(int)
  105.   {
  106.     Self tmp = *this;
  107.     ++*this;
  108.     return tmp;
  109.   }
  110.  
  111.   Self&  operator--()
  112.   {
  113.     if (!node_)
  114.       node_ = g_list_last(*head_);
  115.     else
  116.       node_ = (GList*)g_list_previous(node_);
  117.  
  118.     return *this;
  119.   }
  120.  
  121.   Self operator--(int)
  122.   {
  123.     Self tmp = *this;
  124.     --*this;
  125.     return tmp;
  126.   }
  127.  
  128.   reference operator*()  const 
  129.   {
  130.     return *(pointer)( node_ ? node_->data : glibmm_null_pointer );
  131.   }
  132.   
  133.   pointer operator -> () const { return &operator*(); }
  134. };
  135.  
  136. ///For instance, SList_Iterator< Gtk::Widget >
  137. template <class T>
  138. class SList_Iterator : public List_Iterator_Base<T>
  139. {
  140. public:
  141.   typedef std::forward_iterator_tag iterator_category;
  142.   typedef size_t size_type;
  143.   typedef ptrdiff_t difference_type;
  144.  
  145.   typedef typename List_Iterator_Base<T>::pointer pointer;
  146.   typedef typename List_Iterator_Base<T>::reference reference;
  147.  
  148.   GSList* node_;
  149.   typedef SList_Iterator<T> Self;
  150.  
  151.   SList_Iterator(GSList* node)
  152.    : node_(node)
  153.    {}
  154.  
  155.   SList_Iterator()
  156.    : node_(0)
  157.    {}
  158.  
  159.   SList_Iterator(const Self& src)
  160.   : node_(src.node_)
  161.   {}
  162.  
  163.   bool operator==(const Self& src) const { return node_ == src.node_; }
  164.   bool operator!=(const Self& src) const { return node_ != src.node_; }
  165.  
  166.   Self&  operator++()
  167.   {
  168.     node_ = g_slist_next(node_);
  169.     return *this;
  170.   }
  171.  
  172.   Self operator++(int)
  173.   {
  174.     Self tmp = *this;
  175.     ++*this;
  176.     return tmp;
  177.   }
  178.  
  179.   reference operator*()  const
  180.   {
  181.     g_assert(node_);
  182.     return reinterpret_cast<T&>( node_ ? node_->data : glibmm_null_pointer );
  183.   }
  184.  
  185.   pointer operator -> () const { return &operator*(); }
  186. };
  187.  
  188.  
  189. // This iterator variation returns T_IFace (wrapped from T_Impl)
  190. //  For instance,  List_Cpp_Iterator<GtkWidget, Gtk::Widget> is a little like std::list<Gtk::Widget>::iterator
  191. template<class T_Impl, class T_IFace>
  192. class List_Cpp_Iterator : public List_Iterator_Base<T_IFace>
  193. {
  194. public:
  195.   typedef std::bidirectional_iterator_tag iterator_category;
  196.   typedef size_t size_type;
  197.   typedef ptrdiff_t difference_type;
  198.  
  199.   typedef typename List_Iterator_Base<T_IFace>::pointer pointer;
  200.   typedef typename List_Iterator_Base<T_IFace>::reference reference;
  201.  
  202.   typedef List_Cpp_Iterator<T_Impl, T_IFace> Self;
  203.  
  204.   GList** head_;
  205.   GList* node_;
  206.  
  207.   bool operator==(const Self& src) const { return node_ == src.node_; }
  208.   bool operator!=(const Self& src) const { return node_ != src.node_; }
  209.  
  210.   List_Cpp_Iterator(GList*& head, GList* node )
  211.   : head_(&head), node_(node )
  212.   {}
  213.  
  214.   List_Cpp_Iterator()
  215.   : head_(0), node_(0)
  216.   {}
  217.  
  218.   List_Cpp_Iterator(const Self& src)
  219.   : head_(src.head_), node_(src.node_)
  220.   {}
  221.  
  222.   reference operator*() const
  223.   {
  224.     if (node_ && node_->data)
  225.     {
  226.       //We copy/paste the widget wrap() implementation here,
  227.       //because we can not use a specific Glib::wrap(T_Impl) overload here,
  228.       //because that would be "dependent", and g++ 3.4 does not allow that.
  229.       //The specific Glib::wrap() overloads don't do anything special anyway.
  230.       GObject* cobj = static_cast<GObject*>( (*node_).data );
  231.       
  232.       #ifdef GLIBMM_CAN_USE_DYNAMIC_CAST_IN_UNUSED_TEMPLATE_WITHOUT_DEFINITION
  233.       return *(dynamic_cast<pointer>(Glib::wrap_auto(cobj, false /* take_copy */)));
  234.       #else
  235.       //We really do need to use dynamic_cast<>, so I expect problems if this code is used. murrayc.
  236.       return *(static_cast<pointer>(Glib::wrap_auto(cobj, false /* take_copy */)));
  237.       #endif
  238.       
  239.     }
  240.     
  241.     return *(pointer)glibmm_null_pointer;
  242.   }
  243.  
  244.   pointer operator->() const { return &operator*(); }
  245.  
  246.   Self&  operator++()
  247.   {
  248.     if (!node_)
  249.       node_ = g_list_first(*head_);
  250.     else
  251.       node_ = (GList *)g_list_next(node_);
  252.  
  253.     return *this;
  254.   }
  255.  
  256.   Self operator++(int)
  257.   {
  258.     Self tmp = *this;
  259.     ++*this;
  260.     return tmp;
  261.   }
  262.  
  263.   Self&  operator--()
  264.   {
  265.     if (!node_)
  266.       node_ = g_list_last(*head_);
  267.     else
  268.       node_ = (GList *)g_list_previous(node_);
  269.  
  270.     return *this;
  271.   }
  272.  
  273.   Self operator--(int)
  274.   {
  275.     Self tmp = *this;
  276.     --*this;
  277.     return tmp;
  278.   }
  279.  
  280. };
  281.  
  282. template <class T_Base>
  283. class List_ReverseIterator: private T_Base
  284. {
  285. public:
  286.   typedef typename T_Base::iterator_category iterator_category;
  287.   typedef typename T_Base::size_type         size_type;
  288.   typedef typename T_Base::difference_type   difference_type;
  289.  
  290.   typedef typename T_Base::value_type        value_type;
  291.   typedef typename T_Base::pointer           pointer;
  292.   typedef typename T_Base::reference         reference;
  293.  
  294.   typedef List_ReverseIterator<T_Base>    Self;
  295.  
  296.   bool operator==(const Self& src) const { return T_Base::operator==(src); }
  297.   bool operator!=(const Self& src) const { return T_Base::operator!=(src); }
  298.  
  299.   List_ReverseIterator(GList* const& head, GList* node)
  300.    : T_Base(head, node)
  301.   {}
  302.  
  303.   List_ReverseIterator()
  304.    : T_Base()
  305.   {}
  306.  
  307.   List_ReverseIterator(const Self& src)
  308.   : T_Base(src)
  309.   {}
  310.  
  311.   List_ReverseIterator(const T_Base& src)
  312.   : T_Base(src)
  313.   { ++(*this); }
  314.  
  315.  
  316.   Self& operator++()   {T_Base::operator--(); return *this;}
  317.   Self& operator--()   {T_Base::operator++(); return *this;}
  318.   Self operator++(int) {Self src = *this; T_Base::operator--(); return src;}
  319.   Self operator--(int) {Self src = *this; T_Base::operator++(); return src;}
  320.  
  321.   reference operator*() const { return T_Base::operator*(); }
  322.   pointer operator->()  const { return T_Base::operator->(); }
  323. };
  324.  
  325. template <class T_Base>
  326. class List_ConstIterator: public T_Base
  327. {
  328. public:
  329.   typedef typename T_Base::iterator_category iterator_category;
  330.   typedef typename T_Base::size_type         size_type;
  331.   typedef typename T_Base::difference_type   difference_type;
  332.  
  333.   typedef const typename T_Base::value_type  value_type;
  334.   typedef const typename T_Base::pointer     pointer;
  335.   typedef const typename T_Base::reference   reference;
  336.  
  337.   typedef List_ConstIterator<T_Base> Self;
  338.  
  339.   bool operator==(const Self& src) const { return T_Base::operator==(src); }
  340.   bool operator!=(const Self& src) const { return T_Base::operator!=(src); }
  341.  
  342.   List_ConstIterator(GList* const& head, GList* node)
  343.   : T_Base(head, node)
  344.   {}
  345.  
  346.   List_ConstIterator()
  347.   : T_Base()
  348.   {}
  349.  
  350.   List_ConstIterator(const Self& src)
  351.   : T_Base(src)
  352.   {}
  353.  
  354.   List_ConstIterator(const T_Base& src)
  355.   : T_Base(src)
  356.   {}
  357.  
  358.   Self& operator++()   {T_Base::operator++(); return *this;}
  359.   Self& operator--()   {T_Base::operator--(); return *this;}
  360.   Self operator++(int) {Self src = *this; T_Base::operator++(); return src;}
  361.   Self operator--(int) {Self src = *this; T_Base::operator--(); return src;}
  362.  
  363.   reference operator*() const { return T_Base::operator*(); }
  364.   pointer operator->()   const { return T_Base::operator->(); }
  365. };
  366.  
  367. } // namespace Glib
  368.  
  369. #endif /* DOXYGEN_SHOULD_SKIP_THIS */
  370.  
  371. #endif /* _GLIBMM_CONTAINERS_H */
  372.  
  373.